/* ----------------------------------------------------------------------------

	pax.widget.window.js Copyright (C) 2006, 2008 Mikkel Bergmann, Pointful

	Licence
	-------
	
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

	See lgpl.txt for licence details

---------------------------------------------------------------------------- */

/*
	Script: pax.widget.window
		This is a window widget, that can render windows in various ways
		
	Author:
		Mikkel Bergmann, <http://www.pointful.com>

*/

var pax = pax || {};
pax.widget = pax.widget || {};
pax.widget.window = pax.widget.window || {};

/*	Method: pax.widget.window.init
	Initialises a window
	
	Parameters:		
		target - an element to render the window into
		args - arguments for the grid widget

	Returns:
		nothing

	Example:
		(start code)
			<div id='widget.window.init.example1'>This is my window's content</div>
			[:.
				var myWindow = pax.widget.window.init( pax.$('widget.window.init.example1') );
			:]
		(end)
		This example sets up a simple window, with no options specified.
		
	Example:
		(start code)
			<div id='widget.window.init.example2'>This is my window's content</div>
			[:.
				var myWindow = pax.widget.window.init( pax.$('widget.window.init.example2'), {
					width: 200,
					height: 150
				} );
			:]
		(end)
		This example sets up a simple window, with width and height specified
		
*/
pax.widget.window.init = function( target, args ) {
	args = args || {};
	
	var _target = target;
	target = ( typeof( target ) == 'string' )? pax.$( target ): target;
	
	// Note: this doesn;t work: we MUST have a proper DOM element here, for the model...
	if( target == null )target = { id: _target, blah: 'test' };

	//	Setup the default config values for this widget (used internally for keeping state)
	//	Model of MVC
	var model = pax.defaultArgs( {
		x: 10,										// Position in the window manager defined desktop, still todo
		y: 10,										// Position in the window manager defined desktop, still todo
		width: 500,									// Width of the window (internal - not including chrome)
		height: 200,								// Height of the window - if not specified, window won't scroll
		offsetScrollWidth: 17,						// Pixels to offset for the scrollbar on the right of the grid
		showHeader: true,							// Show the header.
		showFooter: true,							// Show the footer.
		showMinButton: false,						// Show minimise button
		showMaxButton: false,						// Show the maximise button
		showClsButton: true,						// Show the close button
		showOverflow: true,							// Should we allow scrolling on the window content
		draggable: true,							// If we can move the window
		icon: '',									// Image for the icon
		header: '',									// Content of header
		//	TODO: fix the header centering
		headerAlign: 'left',						// The header alignment
		content: target.innerHTML,					// Content of the window.
		padding: 4,									// pixels to pad the window content by
		footer: '',									// Content of footer
		target: target,								// The target DOM element for the window
		targetRight: false,							// This should be an element, if we want the window to appear to the the right of the element
		
		minButtonClick: function( event, args ) {
			// TODO: Hide the window, and notify the window manager
			// If no window manager, we should just display the header of the table.
			console.log( 'min button click - should use window manager to handle this' );
		},
		maxButtonClick: function( event, args ) {
			// TODO: Maximise the window using the window manager
			console.log( 'max button click - should use window manager to handle this' );
		},
		closeButtonClick: function( event, args ) {
			pax.widget.window.cleanup( args.value );
		},
		setHeader: function( heading ) {
			pax.$( this.target.id + '_header' ).innerHTML = heading;
		}
	}, args );

	//	This creates the target
	var windowWidget = pax.widget.init( {
		model: model, 
		template: pax.widget.window.template(),
		target: target,
		render: function() {
			// We override the render method, in order to use the window manager to first display a box, and then render the template into it.
			if( this.model.targetRight ) {
				var myWindow = pax.box.showOnRight( this.target.id, '', 'pWindow', this.model.targetRight );
			} else {
				var myWindow = pax.box.show( this.target.id, '', 'pWindow', this.model.x, this.model.y );
			}
			
			//	Target fix up
			this.target = myWindow;
			this.model.target = myWindow;
			
			pax.template.render( this.template, { target: myWindow, value: this.model } );
			
			return myWindow;
		}
	} );

	//	Set the ID, so it is visible in the model, for rendering in the template, and setting handles, etc...
	windowWidget.model.paxWidgetId = windowWidget.paxWidgetId;
	windowWidget.model.windowWidget = windowWidget;
	windowWidget.render();
	
	return windowWidget;
};


/*	Private method: pax.widget.window.template
	Returns a PAX template for the window
*/
pax.widget.window.cleanup = function( model ) {
	model.windowWidget.destroy();
	pax.box.hide( model.target );
};


/*	Private method: pax.widget.window.template
	Returns a PAX template for the window
*/
pax.widget.window.template = function() {
	var myTemplate = "" +
	// "<div style='width: [:= width :]px'>";
	"<div style='width: [:= (width + 12) :]px'>";	//	Ok, the window is now 12 pixels, plus the border = 14px wider than specified width. 
	
	myTemplate += pax.widget.window.templateHeader();
	
	myTemplate += "" +
		"<div class='pWindowBody' style='width: [:= width + offsetScrollWidth -5 :]'>" +
		// This works for both IE and FF
		"	<div class='pWindowScroll' style='height: [:= height - ( pax.isIe? -2: ( padding * 2) ) :];padding:[:= padding :];[:= !showOverflow ? 'overflow: hidden;': '' :]'>" +
		"		<div id='[:= target.id :]_content'>" +		
		"			[:= content :]" +
		"		</div> " +
		"	</div>" +
		"</div>" +
	"";
		
	myTemplate += pax.widget.window.templateFooter();

	myTemplate += "" +
		"[:. if( draggable ) { " +
		"		windowWidget.addToBindQueue( pax.fx.drag( target, { " +
		"			handle: pax.$( paxWidgetId + '_handle' )";
	if( pax.isIe ) {	//	We do this to insert the hidden iFrame (shim) below the window, so it appears above select boxes
		myTemplate += "" +
		"			," +
		"			callMove: function( args ) { pax.box.setPosition( args.args.element, args.x, args.y ); }," +
		"			callBack: function( args ) { args.args.element.iFrame = null; }";
	}
	myTemplate += "" +
		"		} ) );" +
		"	} " +
		":]" +
	
	"</div>";
	
	
	return myTemplate;
};


pax.widget.window.templateHeader = function() {
	var myTemplate = "" +
		"	<div class='pWindowHeader' style='width: [:= width + offsetScrollWidth -5 :]'>" +
		"		<div style='width: [:= width + offsetScrollWidth -5 :]'>" +
		"			<table cellpadding='0' cellspacing='0'>" +
		"				<tr>" +
		"					<td class='pWindowTD header_left' width='5px'>" +
		"						<div class='pWindowCell header_left' unselectable='on'>&nbsp;</div>" +
		"					</td>" +
		"					[: if( icon != '' ) { :]" +
		"					<td class='pWindowTD icon' width='20px'>" +
		"						<div class='pWindowCell header headerContent' unselectable='on'><img src='[:= icon :]'></div>" +
		"					</td>" +
		"					[: } :]" +
		"					<td id='[:= paxWidgetId + '_handle' :]' class='pWindowTD' width='[:= (width + offsetScrollWidth -60 -5 -5) - ( (icon != '')? 20: 0) :]px'>" +
		
		/*
			TODO:
		
			OK, we need to calculate how to center the text - we should extend it to 
			fit however wide we can, and then calculate how much to indent by.
			ie: if we're not showing min / max button, or icon, we need to indent by that 
			much, instead of showing empty containers, as we do with the buttons presently.
		*/
		
		"						<div id='[:= target.id :]_header' style='[:= 'text-align: ' + headerAlign :]' class='pWindowCell header headerContent' unselectable='on'>[:= header :]</div>" +
		"					</td>" +
		"					<td class='pWindowTD' width='60px'>" +
		"						<div class='pWindowCell header headerContent' unselectable='on'>" +
		"							<table cellpadding='0' cellspacing='0'>" +
		"								<tr>" +
		"									<td width='20px'><span id='minButton_[:= target.id :]'></span></td>" +
		"									<td width='20px'><span id='maxButton_[:= target.id :]'></span></td>" +
		"									<td width='20px'><span id='clsButton_[:= target.id :]'></span></td>" +
		" 									[:." +
		"										if( showMinButton )windowWidget.useWidget( pax.widget.button.init( pax.$('minButton_' + target.id), { height: '28px', func: function(e){minButtonClick( e, args )}, content: '&nbsp;', width: '20px', showChrome: false, baseClass: 'pButtonWindow min' } ) );" +
		"										if( showMaxButton )windowWidget.useWidget( pax.widget.button.init( pax.$('maxButton_' + target.id), { height: '28px', func: function(e){maxButtonClick( e, args )}, content: '&nbsp;', width: '20px', showChrome: false, baseClass: 'pButtonWindow max' } ) );" +
		"										if( showClsButton )windowWidget.useWidget( pax.widget.button.init( pax.$('clsButton_' + target.id), { height: '28px', func: function(e){closeButtonClick( e, args )}, content: '&nbsp;', width: '20px', showChrome: false, baseClass: 'pButtonWindow cls' } ) );" +
		" 									:]" +
		"								</tr>" +
		"							</table>" +
		"						</div>" +
		"					</td>" +
		"					<td class='pWindowTD header_right' width='5px'>" +
		"						<div class='pWindowCell header_right' unselectable='on'>&nbsp;</div>" +
		"					</td>" +
		"				</tr>" +
		"			</table>" +
		"		</div>		" +
		"	</div>" +
	"";
	return myTemplate;
};

pax.widget.window.templateFooter = function() {
	var myTemplate = "" +
		"[: if( showFooter ) { :]" +
		"	<div class='pWindowFooter' style='width: [:= width + offsetScrollWidth -5 :]'>" +
		"		<div style='width: [:= width + offsetScrollWidth -5 :]'>" +
		"			<table cellpadding='0' cellspacing='0'>" +
		"				<tr>" +
		"					<td class='pWindowTD footer_left' width='5px'>" +
		"						<div class='pWindowCell footer_left' unselectable='on'>&nbsp;</div>" +
		"					</td>" +
		"					<td class='pWindowTD' width='[:= width + offsetScrollWidth :]'>" +
		"						<div class='pWindowCell footer'>" +
		"							<table cellpadding='0' cellspacing='1' border='0' width='100%'><tr>" +
		"								<td><span id='[:= target.id :]_footer'>[:= push( footer, {} ) :]</span></td>" +
		"							</tr></table>" +
		"						</div>" +
		"					</td>" +
		"					<td class='pWindowTD footer_right' width='5px'>" +
		"						<div class='pWindowCell footer_right' unselectable='on'>&nbsp;</div>" +
		"					</td>" +
		"				</tr>" +
		"			</table>" +
		"		</div>		" +
		"	</div>" +
		"[: } else { :]" +
		"[: } :]" +
	"";
	return myTemplate;
};